package projectisd.client;

import projectisd.client.LeerlingDelegate;

import java.util.List;

import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.Grid;
import com.google.gwt.user.client.ui.Hyperlink;
import com.google.gwt.user.client.ui.Image;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.RootPanel;
import com.google.gwt.user.client.ui.TextBox;
import com.google.gwt.user.client.ui.HTMLTable.Cell;

/** 
 * In deze klas wordt de interface aangeroepen om een Leerling te kunnen toevoegen
 * in de webbrowse
 * @author Team 2
 * @version 7.0
 */

public class LeerlingGUI {
	/* Constants. */
	private static final String LISTING_ROOT_PANEL = "guiListing";
	private static final String FORM_ROOT_PANEL = "guiForm";
	private static final String STATUS_ROOT_PANEL = "guiStatus";
	private static final String TOOL_BAR_ROOT_PANEL = "guiToolBar";
	private static final int EDIT_LINK = 7;
	private static final int REMOVE_LINK = 8;

	/* GUI Widgets */
	protected Button addButton;
	protected Button updateButton;
	protected Button addNewButton;
	protected TextBox studentNummerField;
	protected TextBox studentVoornaamField;
	protected TextBox studentAchternaamField;
	protected Label titel;
	protected Label status;
	protected Grid listGrid;
	protected Grid formGrid;
	protected Image hulogo;

	/* Data model */
	private List<Leerling> leerlingen;
	private Leerling currentLeerling;
	protected LeerlingDelegate leerlingService;

	/** 
	 * In deze methode worden alle Widgets gemaakt die later weer kunnen worden opgehaald
	 */

	
	public void init() {
		addButton = new Button("Toevoegen");
		addNewButton = new Button("Leerling Toevoegen");
		updateButton = new Button("Update leerling");
		studentNummerField = new TextBox();
		studentVoornaamField = new TextBox();
		studentAchternaamField = new TextBox();
		titel = new Label("Leerlingen beheren");
		status = new Label();
		listGrid = new Grid(2,9);
		hulogo = new Image("http://jansen-schoonhoven.com/Downloads/hulogo.jpg");

		buildForm();
		placeWidgets();
	}
	
	/** 
	 * Hier in worden de widgets gebruikt in de Buildform waar in een grid wordt gebruikt
	 * om de widgets te plaatsen op het scherm
	 */
	

	private void buildForm() {
		formGrid = new Grid(6,3);
		formGrid.setVisible(false);

		formGrid.setWidget(0, 0, titel);
		formGrid.setWidget(0, 2, hulogo);
		formGrid.setWidget(1, 0, new Label("Studentnummer"));
		formGrid.setWidget(1, 1, studentNummerField);


		formGrid.setWidget(2, 0, new Label("Studentvoornaam"));
		formGrid.setWidget(2, 1, studentVoornaamField);

		formGrid.setWidget(3, 0, new Label("Studentachternaam"));
		formGrid.setWidget(3, 1, studentAchternaamField);

		formGrid.setWidget(4, 1, updateButton);
		formGrid.setWidget(4, 0, addButton);

	}
	
	/** 
	 * Hier in worden de widgets zoals listgrid formgrid en status geplaats in
	 * de rootpanel 
	 */


	private void placeWidgets() {
		RootPanel.get(LISTING_ROOT_PANEL).add(listGrid);
		RootPanel.get(FORM_ROOT_PANEL).add(formGrid);
		RootPanel.get(STATUS_ROOT_PANEL).add(status);
		RootPanel.get(TOOL_BAR_ROOT_PANEL).add(addNewButton);
	}
	

	/** 
	 * In deze methode wordt uitgevoerd om bepaalde widgets te kunnen hiden als deze wordt aangeroepen
	 */



	public void hideGui() {
		formGrid.setVisible(false);
		listGrid.setVisible(false);
		status.setVisible(false);
		addNewButton.setVisible(false);
	}
	
	/** 
	 * In deze methode wordt het formulier aangeroepen wat de gebruiker
	 * kan invullen	
	 */


	private void loadForm(Leerling leerling) {
		this.formGrid.setVisible(true);
		currentLeerling = leerling;
		this.studentNummerField.setText(leerling.getStudentnummer());
		this.studentVoornaamField.setText(leerling.getStudentvoornaam());
		this.studentAchternaamField.setText(leerling.getStudentachternaam());        
	}
	
	/** 
	 * In deze methode wordt een Leerling opgeslagen in de database
	 * 
	 */


	private void copyFieldDateToLeerling() {
		currentLeerling.setStudentnummer(studentNummerField.getText());
		currentLeerling.setStudentvoornaam(studentVoornaamField.getText());
		currentLeerling.setStudentachternaam(studentAchternaamField.getText());
	}
	
	/** 
	 * In deze methode wordt verteld wanneer bepaalde knoppen 
	 * zichtbaar mogen zijn zodra er een bepaalde knop wordt geselecteerd
	 * 
	 */


	public void gui_eventListGridClicked(Cell cellClicked) {
		int row = cellClicked.getRowIndex();
		int col = cellClicked.getCellIndex();

		Leerling leerling = this.leerlingen.get(row);
		this.status.setText("Naam was " + leerling.getStudentvoornaam() + " clicked ");

		if (col==EDIT_LINK) {
			this.addNewButton.setVisible(false);
			this.updateButton.setVisible(true);
			this.addButton.setVisible(false);
			loadForm(leerling);
		} else if (col==REMOVE_LINK) {
			if (Window.confirm("Verwijderen leerling?")) {
				this.leerlingService.removeLeerling(leerling);
			}
		}
	}
	
	/** 
	 * In deze methode staat wat er moet gebeuren voordat op Addbutton wordt
	 * geclickt voordat de ingevulde gegevens worden opgeslagen.
	 */


	public void gui_eventAddButtonClicked() {
		if	(studentNummerField.getText().length() == 0 && 
				studentVoornaamField.getText().length() == 0 &&
				studentAchternaamField.getText().length() == 0)
		{	Window.alert("Alle velden moeten gevuld zijn");

		} else if (studentNummerField.getText().length() == 0)
		{	Window.alert("Studentnummer moet gevuld zijn");

		} else if (!studentNummerField.getText().matches("^(0)$|^([1-9][0-9]*)$"))
		{ Window.alert ("Studentnummer bevat letters of tekens");

		} else if (studentVoornaamField.getText().length()== 0)
		{ Window.alert("Voornaam moet gevuld zijn");
		
		} else if (!studentVoornaamField.getText().matches("^[A-Z].*$"))
		{ Window.alert("Voornaam moet beginnen met een hoofdletter");

		} else if (studentAchternaamField.getText().length()== 0)
		{ Window.alert("Achternaam moet gevuld zijn");
		
		} else if (!studentAchternaamField.getText().matches("^[A-Z].*$"))
		{ Window.alert("Achternaam moet beginnen met een hoofdletter");

		} else {
			addNewButton.setVisible(true);
			formGrid.setVisible(false);
			copyFieldDateToLeerling();
			this.leerlingService.addLeerling(currentLeerling);
		}
	}
	

	/** 
	 * In deze methode staat wat er moet gebeuren voordat op Updatebutton wordt
	 * geclickt voordat de ingevulde gegevens worden opgeslagen.
	 */

	public void gui_eventUpdateButtonClicked() {
		if	(studentNummerField.getText().length() == 0 && 
				studentVoornaamField.getText().length() == 0 &&
				studentAchternaamField.getText().length() == 0)
		{	Window.alert("Alle velden moeten gevuld zijn");

		} else if (studentNummerField.getText().length() == 0)
		{	Window.alert("Studentnummer moet gevuld zijn");

		} else if (!studentNummerField.getText().matches("^(0)$|^([1-9][0-9]*)$"))
		{ Window.alert ("Studentnummer bevat letters of tekens");

		} else if (studentVoornaamField.getText().length()== 0)
		{ Window.alert("Voornaam moet gevuld zijn");
		
		} else if (!studentVoornaamField.getText().matches("^[A-Z].*$"))
		{ Window.alert("Voornaam moet beginnen met een hoofdletter");
		

		} else if (studentAchternaamField.getText().length()== 0)
		{ Window.alert("Achternaam moet gevuld zijn");
		
		} else if (!studentAchternaamField.getText().matches("^[A-Z].*$"))
		{ Window.alert("Achternaam moet beginnen met een hoofdletter");
	
		} else {
			addNewButton.setVisible(true);
			formGrid.setVisible(false);
			copyFieldDateToLeerling();
			this.leerlingService.updateLeerling(currentLeerling);
		}
	}
	
	/** 
	 * In deze methode staat wat er moet gebeuren voordat er op de
	 * knop AddnewButton wordt geklikt er wordt hier dus het formulier
	 * getoont wat in de buildform wordt gemaakt
	 */

	public void gui_eventAddNewButtonClicked() {
		this.addNewButton.setVisible(false);
		this.updateButton.setVisible(false);
		this.addButton.setVisible(true);
		Leerling leerling = new Leerling();
		loadForm(leerling);
	}
	
	/** 
	 * In deze methode wordt de lijst getoont met een for
	 */


	public void service_eventListRetrievedFromService(List<Leerling> result) {
		status.setText("Retrieved leerling list");
		status.setVisible(true);

		//formGrid.setVisible(false);
		listGrid.setVisible(true);
		status.setVisible(true);
		addNewButton.setVisible(true);

		this.leerlingen = result;
		this.listGrid.clear();
		this.listGrid.resizeRows(this.leerlingen.size());
		int row = 0;
		this.addNewButton.setVisible(true);

		for (Leerling leerling : result) {
			this.listGrid.setWidget(row, 0, new Label (leerling.getStudentnummer()));
			this.listGrid.setWidget(row, 1, new Label (leerling.getStudentvoornaam()));
			this.listGrid.setWidget(row, 2, new Label (leerling.getStudentachternaam()));
			this.listGrid.setWidget(row, EDIT_LINK, new Hyperlink("Edit", null));
			this.listGrid.setWidget(row, REMOVE_LINK, new Hyperlink("Remove", null));
			row ++;
		}
	}
	
	/** 
	 * In deze methode wordt verteld of de gegevens goed zijn toegevoegd
	 * aan de database zo niet toont hij een status tekst met het resultaat
	 */

	public void service_eventAddLeerlingSuccessful() {
		status.setText("Leerling was successfully added");
		this.leerlingService.listLeerlingen();
	}
	
	/** 
	 * In deze methode wordt verteld of de date goed is geupdated
	 * aan de database zo niet toont hij een status tekst met het resultaat
	 */

	public void service_eventUpdateSuccessful() {
		status.setText("Leerling was successfully updated");
		this.leerlingService.listLeerlingen();
	}
	
	/** 
	 * In deze methode wordt verteld of de date goed is verwijderd
	 * aan de database zo niet toont hij een status tekst met het resultaat
	 */
	public void service_eventRemoveLeerlingSuccessful() {
		status.setText("Leerling was removed");
		this.leerlingService.listLeerlingen();
	}
	
	/** 
	 * In deze methode wordt verteld of de date niet goed is geupdated
	 * aan de database zo niet toont hij een status tekst met het resultaat
	 */

	public void service_eventUpdateLeerlingFailed(Throwable caught) {
		status.setText("Update leerling failed");
	}
	
	/** 
	 * In deze methode wordt verteld of de date niet goed is toegevoegd
	 * aan de database zo niet toont hij een status tekst met het resultaat
	 */

	public void service_eventAddLeerlingFailed(Throwable caught) {
		status.setText("Unable to update leerling");
	}
	
	/** 
	 * In deze methode wordt verteld of de date niet goed is verwijderd
	 * aan de database zo niet toont hij een status tekst met het resultaat
	 */

	public void service_eventRemoveLeerlingFailed(Throwable caught) {
		status.setText("Remove leerling failed");
	}
	
	/** 
	 * In deze methode wordt verteld of de date niet goed wordt getoont
	 * in de lijst
	 */

	public void service_eventListLeerlingFailed(Throwable caught) {
		status.setText("Unable to get leerling list");

	}

}
